//
// Created by cube on 2020/10/22.
//

#ifndef COMPILERDOMEA1_POOLS_H
#define COMPILERDOMEA1_POOLS_H

#include "../Base/Server.h"

namespace Lib{

    template <typename T = uint32_t >
    class IdPool{
    public:
        T get(){
            T rul = 0;
            if(__freeId.empty()){
                rul = __baseid++;
            }else{
                auto p = __freeId.begin();
                std::pair<T,T>& ids = *p;
                rul = ids.first;
                if(ids.first == ids.second)__freeId.erase(p);
                else ids.first++;
            }
            return rul;
        }
        void push(const T& id){
            if(id >= __baseid)return;
            auto p = __freeId.begin();
            while(true){
                if(p == __freeId.end()){
                    __freeId.push_back(std::make_pair(id,id));
                    __freeId.sort([](
                            const std::pair<T,T>& a,
                            const std::pair<T,T>& b) -> bool{
                        return a.first < b.first;
                    });
                    break;
                }
                else if(p->first <= id && p->second >= id)return;
                else if(id == p->first-1){p->first = id;return;}
                else if(id == p->second+1){
                    p->second = id;
                    auto p_next = p;p_next++;
                    if(p_next != __freeId.end()){
                        if(p_next->first == p->first){
                            p->second = p_next->second;
                            __freeId.erase(p_next);
                        }
                    }
                    if(p->second == __baseid-1){
                        __baseid = p->first;
                        __freeId.erase(p);
                    }
                    break;
                }
                p++;
            }
        }
    private:
        T    __baseid;
        std::list<std::pair<T,T>>     __freeId;
    };


}


#endif //COMPILERDOMEA1_POOLS_H
